#include "common.hpp"

int main()
{
    Log("Client pid is : ", Debug) << getpid() << endl;

    // 创建公共的Key值
    key_t k = ftok(PATH_NAME, PROJ_ID); // typedef int key_t
    if (k < 0)
    {
        Log("create key failed", Error) << " client key : " << ConvertToHex(k) << endl;
        exit(1);
    }
    Log("create key done", Debug) << " client key : " << ConvertToHex(k) << endl;

    // 获取共享内存
    int shmid = shmget(k, SHM_SIZE, 0);
    if (shmid < 0)
    {
        Log("obtain shm failed", Error) << " shmid : " << shmid << endl;
        exit(2);
    }
    Log("obtain shm success", Debug) << " shmid : " << shmid << endl;
    //sleep(10);

    // 将指定的共享内存 挂接到自己的地址空间
    char *shmaddr = (char *)shmat(shmid, nullptr, 0);
    if (shmaddr == nullptr)
    {
        Log("attach shm failed", Error) << " shmid : " << shmid << endl;
        exit(3);
    }
    Log("attach shm success", Debug) << " shmid : " << shmid << endl;
    //sleep(10);

    // 开始通信   client将共享内存看做一个char 类型的buffer
    int fd = OpenFIFO(FIFO_NAME, WRITE);
    while (true)
    {
        ssize_t s = read(0, shmaddr, SHM_SIZE - 1); // 从stdin读数据存到shm
        if (s > 0)
        {
            shmaddr[s - 1] = 0; // abcd\n ==> abcd0
            Wake(fd); // 客户端向shm写数据后 通过向命名管道写数据来唤醒服务端
            if (strcmp(shmaddr, "quit") == 0)
                break;
        }
    }
    CloseFifo(fd);

    /* 每一次都向共享内存的起始地址写入
    char *msg = "hello server, I'm Client. my pid: %d, inc: %c\n";
    for (char a = 'a'; a <= 'z'; a++)
        {
            shmaddr[a - 'a'] = a;                              // 直接当成字符数组来看待
            snprintf(shmaddr, SHM_SIZE - 1, msg, getpid(), a); // 库函数格式化输入数据
            sleep(1);
        }
        strcpy(shmaddr, "quit");
    */

    // 删除映射
    int n = shmdt(shmaddr);
    assert(n != -1);
    (void)n;
    Log("detach shm success", Debug) << " shmid : " << shmid << endl;
    //sleep(10);

    // client不需要chmctl删除
    return 0;
}